#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QSettings>

// #include "kzfqgraphicsitemgroup.h"
#include <QPen>

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // ui->L_img->setMouseTracking(true);//设置鼠标跟踪
    // setMouseTracking(true);//设置鼠标跟踪

    // 只能输入数字
    // ui->LE_caliDiameter->setValidator(new QRegExpValidator(QRegExp("[0-9]+$")));
    // ui->LE_caliGain->setValidator(new QRegExpValidator(QRegExp("[0-9]+$")));

    // 只能输入数字 . -
    // QRegExp exp("[0-9\\.-]+$");
    // QValidator *Validator = new QRegExpValidator(exp);
    // ui->LE_caliDiameter->setValidator(Validator);
    // ui->LE_caliGain->setValidator(Validator);

    new QDoubleValidator();
    ui->LE_caliDiameter->setValidator(new QDoubleValidator(0, 6, 4));
    ui->LE_caliGain->setValidator(new QDoubleValidator(0, 2, 1));

    connect(ui->btn_cali,       &QAbstractButton::clicked, this, &MainWindow::slots_btn_cali);
    connect(ui->btn_caliFin,    &QAbstractButton::clicked, this, &MainWindow::slots_btn_caliFin);
    connect(ui->btn_open,       &QAbstractButton::clicked, this, &MainWindow::slots_btn_open);
    connect(ui->btn_close,      &QAbstractButton::clicked, this, &MainWindow::slots_btn_close);
    connect(ui->btn_reflash,    &QAbstractButton::clicked, this, &MainWindow::slots_btn_reflash);
    connect(ui->btn_save_img,   &QAbstractButton::clicked, this, &MainWindow::slots_btn_save_img);
    connect(ui->btn_open_img,   &QAbstractButton::clicked, this, &MainWindow::slots_btn_open_img);
    connect(ui->btn_open_video, &QAbstractButton::clicked, this, &MainWindow::slots_btn_open_video);
    connect(ui->btn_save_video, &QAbstractButton::clicked, this, &MainWindow::slots_btn_save_video);

    connect(ui->btn_line,       &QAbstractButton::clicked, this, &MainWindow::slots_btn_draw_line);
    connect(ui->btn_circle,     &QAbstractButton::clicked, this, &MainWindow::slots_btn_draw_circle);
    connect(ui->btn_polygeon,   &QAbstractButton::clicked, this, &MainWindow::slots_btn_draw_polygeon);
    connect(ui->btn_squareness, &QAbstractButton::clicked, this, &MainWindow::slots_btn_draw_squareness);
    connect(ui->btn_angle,      &QAbstractButton::clicked, this, &MainWindow::slots_btn_angle);
    connect(ui->btn_repeal,     &QAbstractButton::clicked, this, &MainWindow::slots_btn_repeal);
    connect(ui->btn_del,        &QAbstractButton::clicked, this, &MainWindow::slots_btn_del);
    connect(ui->btn_clear,      &QAbstractButton::clicked, this, &MainWindow::slots_btn_clear);

    // QButtonGroup RBg_cali;// = new QButtonGroup();
    RBg_cali.addButton(ui->RB_autoCircle, 0);
    RBg_cali.addButton(ui->RB_manulLine, 1);
    RBg_cali.addButton(ui->RB_other, 2);

    // 使用 buttonToggled（QAbstractButton*，bool） 而不是 buttonToggled（QAbstractButton*， bool） [clazy-connect-not-normalized]
    connect(&RBg_cali, SIGNAL(buttonToggled(QAbstractButton*, bool)), this, SLOT(slot_toggled_rbg_cali(QAbstractButton*, bool)));
    // connect(&RBg_cali,  &QButtonGroup::buttonClicked,   this, &MainWindow::slot_toggled_x);

    connect(&cap,       &user_capture::user_circle_got, this, &MainWindow::graphicsViewUpdate);
// void buttonToggled(QAbstractButton *, bool);
    slots_btn_reflash(true);//刷新一次摄像头
    ui->GV_img->setAlignment(Qt::AlignLeft|Qt::AlignTop);//锁定view与scence原点
    ui->GV_img->setSceneRect(QRectF(QPointF(0, 0), QSizeF(ui->GV_img->width(), ui->GV_img->height())));//设置场景大小,就不会出现场景缩放滑条
    ui->GV_img->setRenderHint(QPainter::Antialiasing, false);
    ui->GV_img->setOptimizationFlags(QGraphicsView::DontSavePainterState);
    ui->GV_img->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
    ui->GV_img->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    ui->GV_img->setDragMode(QGraphicsView::RubberBandDrag);//QGraphicsView::ScrollHandDrag);RubberBandDrag
    ui->GV_img->setInteractive(true);
    ui->GV_img->setStyleSheet("background: transparent;border:0px");//控件透明 没有东西的时候
    ui->GV_img->move(0,0);
    ui->GV_img->setScene(&RLdraw.DrawScene);

    ui->L_img->move(0,0);

    connect(ui->GV_img,       &kzfQGraphicsView::SmouseLeftPress,       &RLdraw,    &cvRealtimePaint::slots_mouse_left_press);
    connect(ui->GV_img,       &kzfQGraphicsView::SmouseRigthPress,      &RLdraw,    &cvRealtimePaint::slots_mouse_right_press);
    connect(ui->GV_img,       &kzfQGraphicsView::SmouseRelease,         &RLdraw,    &cvRealtimePaint::slots_mouse_release);
    connect(ui->GV_img,       &kzfQGraphicsView::SmouseMove,            &RLdraw,    &cvRealtimePaint::slots_mouse_move);

    ui->btn_line->setDown(false);
    ui->btn_circle->setDown(false);
    ui->btn_polygeon->setDown(false);
    ui->btn_squareness->setDown(false);

    cap.start();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::slots_btn_open(bool enabled)
{
    int capNum = ui->cb_cap->currentIndex();

    cap.user_cap_open(capNum);
    if(cap.is_user_cap_opened()==false){
        return;
    }
    cap.user_cap_start();

    ui->btn_open->setEnabled(false);
    ui->btn_close->setEnabled(true);
    ui->btn_save_img->setEnabled(true);
    ui->btn_save_video->setEnabled(true);

    ui->frame->setFixedSize(QSize(cap.user_get(CV_CAP_PROP_FRAME_WIDTH)+10, cap.user_get(CV_CAP_PROP_FRAME_HEIGHT)+10));
    ui->L_img->setFixedSize(QSize(cap.user_get(CV_CAP_PROP_FRAME_WIDTH), cap.user_get(CV_CAP_PROP_FRAME_HEIGHT)));
    ui->GV_img->setFixedSize(QSize(cap.user_get(CV_CAP_PROP_FRAME_WIDTH), cap.user_get(CV_CAP_PROP_FRAME_HEIGHT)));
    ui->GV_img->setAlignment(Qt::AlignLeft|Qt::AlignTop);//锁定view与scence原点
    ui->GV_img->setSceneRect(QRectF(QPointF(0, 0), QSizeF(ui->GV_img->width(), ui->GV_img->height())));//锁定大小,不出现缩放条

    ui->L_img->move(QPoint(5, 5));
    ui->GV_img->move(QPoint(5, 5));
    connect(&cap, &user_capture::user_img_done, this, &MainWindow::MainImgProcessing);
    RLdraw.DrawScene.clear();

    ui->GV_img->update();
}

void MainWindow::slots_btn_close(bool enabled)
{

    cap.user_cap_close();
    ui->btn_open->setEnabled(true);
    ui->btn_close->setEnabled(false);
    ui->btn_save_img->setEnabled(false);
    ui->btn_save_video->setEnabled(false);

    ui->btn_save_video->setText("开始录像");
    cap.user_cap_save_video_stop();
    disconnect(&cap, &user_capture::user_img_done, this, &MainWindow::MainImgProcessing);
}

void MainWindow::slots_btn_reflash(bool enabled)
{

    ui->cb_cap->clear();

    QList<QString> capInfos = cap.user_cap_scan();

    foreach(QString info , capInfos){
        qDebug()<<info;
        ui->cb_cap->addItem(info);
    }

}

void MainWindow::slots_btn_save_img(void)
{

    qDebug("save img");
    string path = "d:/debug1.jpg";
    if(cap.user_cap_save_img(path)==false){
        qDebug("save err");
    }

}

void MainWindow::slots_btn_open_img(void)
{
    //打开图片文件，选择图片
    QString filename = QFileDialog::getOpenFileName(this,tr("Open Image"),QDir::homePath(),tr("(*.jpg)\n(*.bmp)\n(*.png)"));
    // qDebug()<<"filename:"<<filename;
    if(filename.length()==0){
        return;
    }

    string path = filename.toStdString();
    QPixmap src_img = cap.user_img_open(path);
    ui->L_img->setPixmap(src_img);
    ui->btn_save_img->setEnabled(true);

}

void MainWindow::slots_btn_open_video(void)
{

    if(cap.is_user_recording()){
        ui->btn_save_video->setText("开始录像");
        cap.user_cap_save_video_stop();
    }
    if(cap.is_user_cap_opened()){
        cap.user_cap_close();
        ui->btn_open->setEnabled(true);
        ui->btn_close->setEnabled(false);
    }
    string path = "e:/xxx.avi";
    cap.user_video_open(path);
    ui->btn_save_img->setEnabled(true);
    connect(&cap, &user_capture::user_img_done, this, &MainWindow::MainImgProcessing);

}

void MainWindow::slots_btn_save_video(void)
{

    if(cap.is_user_cap_opened()==false){
        return;
    }
    if(ui->btn_save_video->text()=="停止录像"){
        qDebug("停止录像");
        ui->btn_save_video->setText("开始录像");
        cap.user_cap_save_video_stop();
    }else{
        qDebug("开始录像");
        ui->btn_save_video->setText("停止录像");
        string path = "d:/debugvideo.mp4";
        cap.user_cap_save_video_start(path);
    }

}

void MainWindow::MainImgProcessing(const QPixmap & pi)
{

    //显示到label
    ui->L_img->setPixmap(pi);
}

void MainWindow::graphicsViewUpdate(const int & num)
{
    /*
        校验中识别到圆 并标出
    */
    bool isSelected = 0;
    int pos = 0;
    float diameter = 0;
    float gain = 0;

    if(cap.cameraParm.calibMode != kzfCaptureParm::circleAutoMode){
        RLdraw.DrawScene.clear();
        RLdraw.DrawScene.update();
        return;
    }

    QList<QGraphicsItem *> sItems = RLdraw.DrawScene.items();

    foreach (QGraphicsItem *i, sItems) {
        if(i->isSelected()==true){
            qDebug()<<"selected me "<<pos;
            isSelected = 1;
            // qDebug()<<cap.cRects.at(cap.cRects.length() - pos - 1).center()<<cap.cRects.at(cap.cRects.length() - pos - 1).width()<<cap.cRects.at(cap.cRects.length() - pos - 1).height();
            //用户点选了一个圆,计算圆形的面积,并完成整个校验操作
            //圆面积用相似点计算,获取当前圆形位置,发散数点,并求平均值
            diameter = ui->LE_caliDiameter->text().toFloat();
            gain = ui->LE_caliGain->text().toFloat();
            // qDebug()<<"get le:"<<diameter<<gain;

            if(diameter>0 && gain>0){
                ui->btn_caliFin->setEnabled(true);
            }else{
                ui->btn_caliFin->setEnabled(false);
            }

            break;
        }
        pos++;
    }

    if(isSelected){
        return;
    }

    ui->btn_caliFin->setEnabled(false);
    RLdraw.DrawScene.clear();
    RLdraw.manualDrawCircle(cap.cRects);//重新画识别到的圆形
    RLdraw.DrawScene.update();
}

//=====================================================================


//-------------------画图部分-------------------------------------------
void MainWindow::slots_btn_draw_line(void)
{
    if(RLdraw.drawingType!=cvRealtimePaint::typeLine){
        RLdraw.drawingNullMode();
        RLdraw.drawingLineMode();
        ui->btn_line->setChecked(true);
    }else{
        ui->btn_line->setChecked(false);
        RLdraw.drawingNullMode();
    }

    ui->btn_circle->setChecked(false);
    ui->btn_polygeon->setChecked(false);
    ui->btn_squareness->setChecked(false);
    ui->btn_angle->setChecked(false);
}

void MainWindow::slots_btn_draw_circle(void)
{
    if(RLdraw.drawingType!=cvRealtimePaint::typeCircle){
        RLdraw.drawingNullMode();
        RLdraw.drawingCircleMode();
        ui->btn_circle->setChecked(true);
    }else{
        ui->btn_circle->setChecked(false);
        RLdraw.drawingNullMode();
    }

    ui->btn_line->setChecked(false);
    ui->btn_polygeon->setChecked(false);
    ui->btn_squareness->setChecked(false);
    ui->btn_angle->setChecked(false);
}

void MainWindow::slots_btn_draw_polygeon(void)
{
    RLdraw.drawingNullMode();

    if(RLdraw.drawingType!=cvRealtimePaint::typePolygons){
        RLdraw.drawingPolygeonMode();
        ui->btn_polygeon->setChecked(true);
    }else{
        ui->btn_polygeon->setChecked(false);
    }

    ui->btn_line->setChecked(false);
    ui->btn_circle->setChecked(false);
    ui->btn_squareness->setChecked(false);
    ui->btn_angle->setChecked(false);
}

void MainWindow::slots_btn_draw_squareness(void)
{
    RLdraw.drawingNullMode();

    if(RLdraw.drawingType!=cvRealtimePaint::typeRect){
        RLdraw.drawingSquarenessMode();
        ui->btn_squareness->setChecked(true);
    }else{
        ui->btn_squareness->setChecked(false);
    }

    ui->btn_line->setChecked(false);
    ui->btn_polygeon->setChecked(false);
    ui->btn_circle->setChecked(false);
    ui->btn_angle->setChecked(false);
}

void MainWindow::slots_btn_angle(void)
{
    RLdraw.drawingNullMode();

    if(RLdraw.drawingType!=cvRealtimePaint::typeAngle){
        RLdraw.drawingAngleMode();
        ui->btn_angle->setChecked(true);
    }else{
        ui->btn_angle->setChecked(false);
    }

    ui->btn_line->setChecked(false);
    ui->btn_polygeon->setChecked(false);
    ui->btn_squareness->setChecked(false);
    ui->btn_circle->setChecked(false);
}

void MainWindow::slots_btn_del(void)
{

}

void MainWindow::slots_btn_repeal(void)
{
    QString pathStr = "config.ini";
    qDebug()<<QFile::exists(pathStr);

    QSettings settings(pathStr, QSettings::IniFormat);

    qDebug()<<"read data";
    QStringList allKeys = settings.allKeys();
    foreach (QString x, allKeys) {
        qDebug()<<x;
    }
    settings.beginGroup("config");

    qDebug()<<settings.value("user").toString();
    qDebug()<<settings.value("camera-weight").toString();
    qDebug()<<settings.value("camera-hight").toString();
    qDebug()<<settings.value("umPerPixel").toString();
    qDebug()<<settings.value("camera_name").toString();

    settings.endGroup();
}

void MainWindow::slots_btn_clear(void)
{
    qDebug()<<"write data";

    // setting.readJsonFileToRootObject(QString("./mySetting.json"));
    setting.readJsonFileToRootObject(QString("./wsetting.json"));
    setting.analysisJsonData();
    setting.dataToJson();
    setting.writeRootObjectToJsonFile(QString("./wsetting.json"));
}

//=====================================================================



//-------------------像素校准-------------------------------------------
void MainWindow::slots_btn_cali(void)
{
    RLdraw.DrawScene.clear();
    RLdraw.drawingLists.clear();
    RLdraw.DrawScene.update();

    cap.cameraParm.calibStartSet();
    RLdraw.drawingType = cvRealtimePaint::typeCaliCircle;

    qDebug()<<"start cali";

    ui->L_caliLead->clear();
    ui->L_caliLead->setText("提示:开始标定参数,选择标定类型,根据提示进行操作");

    ui->RB_autoCircle->setEnabled(true);
    ui->RB_manulLine->setEnabled(true);
    ui->RB_other->setEnabled(true);

    ui->RB_autoCircle->setChecked(false);
    ui->RB_manulLine->setChecked(false);
    ui->RB_other->setChecked(true);

    ui->LE_caliDiameter->clear();
    ui->LE_caliDiameter->setEnabled(true);
    ui->LE_caliGain->clear();
    ui->LE_caliGain->setEnabled(true);

    // ui->btn_caliFin->setEnabled(true);
}

void MainWindow::slot_toggled_rbg_cali(QAbstractButton * btn, bool x)
{
    qDebug()<<"slot_toggled_rbg_cali"<<ui->RB_autoCircle->isChecked()<<ui->RB_manulLine->isChecked()<<ui->RB_other->isChecked();

    if(ui->RB_autoCircle->isChecked() == true){
        cap.cameraParm.calibMode = kzfCaptureParm::circleAutoMode;
        cap.cameraParm.calibState = kzfCaptureParm::calibTypeselected;
        ui->L_caliLead->clear();
        ui->L_caliLead->setText("提示:已经选择自动圆模式,放入圆形校准片,鼠标点选识别到的圆,输入实际直径");
    }else if(ui->RB_manulLine->isChecked() == true){
        cap.cameraParm.calibMode = kzfCaptureParm::lineManualMode;
        cap.cameraParm.calibState = kzfCaptureParm::calibTypeselected;
        ui->L_caliLead->clear();
        ui->L_caliLead->setText("提示:已经选择手动改直线模式,放入直线校准片,鼠标画出一段线段,输入实际长度");
    }else{
        cap.cameraParm.calibMode = kzfCaptureParm::nullMode;
        cap.cameraParm.calibState = kzfCaptureParm::calibStarted;
        ui->L_caliLead->clear();
        ui->L_caliLead->setText("提示:选择正确的校准模式,开始校准");
    }
}


void MainWindow::slots_btn_caliFin(void)
{
/*
    根据
        圆面积  S
        输入的圆直径  D
        放大倍数  G
    像素比 paxelPreUm = (D * G) / (sqrt(S/PI) * 2)
*/
    int pos = 0;
    float diameter = 0;
    float gain = 0;

    QList<QGraphicsItem *> sItems = RLdraw.DrawScene.items();

    foreach (QGraphicsItem *i, sItems) {
        if(i->isSelected()==true){

            diameter = ui->LE_caliDiameter->text().toFloat();
            gain = ui->LE_caliGain->text().toFloat();

            if(diameter>0 && gain>0){
                //paxelPreUm = (D * G) / (sqrt(S/PI) * 2)
                cap.cameraParm.umPerPixel = (ui->LE_caliDiameter->text().toFloat() * ui->LE_caliGain->text().toFloat()) / (sqrt(cap.circleLists.at(cap.cRects.length() - pos - 1).area/3.1415926)*2);
                RLdraw.umPerPixel = cap.cameraParm.umPerPixel;
                qDebug()<<"start"<<cap.cRects.at(cap.cRects.length() - pos - 1).center()<<cap.cRects.at(cap.cRects.length() - pos - 1).width()<<cap.cRects.at(cap.cRects.length() - pos - 1).height();
                qDebug()<<cap.circleLists.at(cap.cRects.length() - pos - 1).centerPoint<<cap.circleLists.at(cap.cRects.length() - pos - 1).area;
                qDebug()<<cap.cameraParm.umPerPixel;

                QString strShow;
                strShow.append("标定完成");
                strShow.append(QString::number(cap.cameraParm.umPerPixel, 'f', 6));

                int ret = QMessageBox::information(NULL, "标定完成", strShow, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);

                if(ret==QMessageBox::Yes){
                    qDebug()<<"finish:"<<ret;

                    cap.cameraParm.calibDoneSet();
                    cap.cameraParm.imgHight = 480;
                    cap.cameraParm.imgWidth = 640;
                    cap.cameraParm.cameraGain = gain;

                    ui->btn_caliFin->setEnabled(false);
                    ui->LE_gain->setText(QString::number(gain, 'f', 2));
                    ui->LE_xDPI->setText(QString::number(cap.cameraParm.umPerPixel, 'f', 6));
                    ui->LE_yDPI->setText(QString::number(cap.cameraParm.umPerPixel, 'f', 6));
                    ui->RB_autoCircle->setEnabled(false);
                    ui->RB_manulLine->setEnabled(false);
                    ui->RB_other->setEnabled(false);
                    ui->L_caliLead->setText("提示:");
                    ui->LE_caliDiameter->clear();
                    ui->LE_caliGain->clear();

                    //清场景
                    RLdraw.DrawScene.clear();
                    RLdraw.DrawScene.update();
                    RLdraw.drawingLists.clear();
                    cap.cRects.clear();
                    cap.circleLists.clear();

                }else if(ret==QMessageBox::No){
                    qDebug()<<"again:"<<ret;
                }
            }
            break;
        }
        pos++;
    }

}
